package com.alpha.common.service;

import com.alpha.common.schemas.dictionaries.Dictionary;
import com.alpha.common.schemas.dictionaries.DictionaryRepository;
import com.alpha.common.schemas.dictionaries.DictionaryService;
import com.alpha.core.utils.CollectionUtil;
import com.alpha.service.annotation.DistributedLock;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 字典服务扩展
 *
 * @author chenruwan
 * @since 2022-01-01
 */
@Service
@Primary
public class DictionaryServiceImpl extends ServiceImpl<DictionaryRepository, Dictionary> implements DictionaryService {
    @Override
    @Transactional(rollbackFor = Exception.class)
    @DistributedLock("dictionaries")
    public boolean saveOrUpdateBatch(Collection<Dictionary> dictionaries) {
        List<Dictionary> exists = super.list();
        for (Dictionary dictionary : dictionaries) {
            Optional<Dictionary> found = exists.stream().filter(e -> e.getCode().equals(dictionary.getCode())
                    && e.getParentId().equals(dictionary.getParentId())).findFirst();
            if (found.isEmpty()) {
                // 新增字典
                super.save(dictionary);
                dictionary.getChildren().forEach(e -> e.setParentId(dictionary.getId()));
                super.saveOrUpdateBatch(dictionary.getChildren());
                continue;
            }

            dictionary.setId(found.get().getId());
            updateIfChanged(dictionary, found.get());

            dictionary.getChildren().forEach(e -> e.setParentId(dictionary.getId()));
            List<Dictionary> existedChildren = exists.stream()
                    .filter(e -> e.getParentId().equals(dictionary.getId()))
                    .collect(Collectors.toList());
            for (Dictionary child : existedChildren) {
                Optional<Dictionary> optional = findByCode(dictionary.getChildren(), child.getCode());
                if (optional.isEmpty()) {
                    // 删除枚举
                    super.removeById(child.getId());
                    continue;
                }
                updateIfChanged(optional.get(), child);
            }

            // 新增枚举
            List<Dictionary> collect = dictionary.getChildren().stream()
                    .filter(e -> findByCode(existedChildren, e.getCode()).isEmpty())
                    .collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(collect)) {
                super.saveBatch(collect);
            }
        }
        return true;
    }

    private void updateIfChanged(Dictionary dictionary, Dictionary existed) {
        dictionary.setId(existed.getId());
        if (!dictionary.getValue().equals(existed.getValue())
                || !Objects.equals(dictionary.getName(), existed.getName())) {
            // 有变化才更新
            super.updateById(dictionary);
        }
    }

    private Optional<Dictionary> findByCode(List<Dictionary> dictionaries, String code) {
        return dictionaries.stream().filter(e -> e.getCode().equals(code)).findFirst();
    }
}
